﻿using HMS.Core.Abstractions;
using HMS.Core.Exceptions;
using HMS.Core.Impl;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace HMS.Core;

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddModelRuntimeInitializer(this IServiceCollection services)
    {
        services.AddScoped<IModelRuntimeInitializerProvider, ModelRuntimeInitializerProvider>();

        return services;
    }

    public static IServiceCollection AddMultiTenantSubSystemDbContext<TContext>(this IServiceCollection services, Action<DbContextOptionsBuilder> optionsAction)
        where TContext : DbContext
    {
        services.AddDbContext<DbContext, TContext>((sp, options) =>
        {
            var tenantService = sp.GetRequiredService<ITenantService>();

            var schema = tenantService.GetSchema();

            if (!string.IsNullOrEmpty(schema))
            {
                var modelBuilderProvider = sp.GetRequiredService<IModelBuilderProvider>();
                var modelRuntimeInitializerProvider = sp.GetRequiredService<IModelRuntimeInitializerProvider>();

                var modelBuilder = modelBuilderProvider.GetModelBuilder();

                modelBuilder.Model.SetDefaultSchema(schema);

                modelBuilder.ApplyConfigurationsFromAssembly(typeof(TContext).Assembly);

                var model = modelRuntimeInitializerProvider
                    .ModelRuntimeInitializer.Initialize(modelBuilder.FinalizeModel());

                optionsAction.Invoke(options);

                options
                    .EnableDetailedErrors()
                    .UseModel(model);
            }
            else
            {
                throw new TenantNotAuthenticatedException("请先登录租户系统");
            }
        });

        return services;
    }
}